package edu.xalead.版本三;

import java.util.ArrayList;
import java.util.Random;
import java.util.Stack;

import static sun.swing.MenuItemLayoutHelper.max;

public class Core {
    /**
     * @author GodofOrange
     *    棋盘数据结构
     */
        //棋盘大小
        private int[][] core;
        private int x;
        private int y;
        //记录下棋的类
        class Chess{
            int x;
            int y;
            public Chess(int x,int y) {
                this.x=x;
                this.y=y;
            }
        }
        //栈
        Stack<Chess> stack;
        //构造方法
        public Core(int x,int y) {
            stack = new Stack<>();
            core = new int[x][y];
            this.x=x;
            this.y=y;
        }
        //检查该地是否有空位置
        private boolean __CanInput(int x,int y) {
            if(core[x][y]==0) return true;
            else return false;
        }
        //判断输赢
        private int checkVictory(int x,int y,int var) {
            //横向判断
            int trans = 0;
            for(int i=x-4;i<x+5;i++) {
                if(i<0||i>=this.x) continue;
                if(core[i][y]==var) {
                    trans++;
                }
                else {
                    trans=0;
                }
                if(trans==5) return var;
            }
            //纵向判断
            int longitudinal = 0;
            for(int i=y-4;i<y+5;i++) {
                if(i<0||i>=this.y) continue;
                if(core[x][i]==var) {
                    longitudinal++;
                }
                else {
                    longitudinal=0;
                }
                if(longitudinal==5) return var;
            }
            //从左上到右下
            int leftUPToDown = 0;
            for(int i=x-4,j=y+4;i<x+5&&j>y-5;i++,j--) {
                if(i<0||i>=this.x||j<0||j>=this.y) continue;
                if(core[i][j]==var) {
                    leftUPToDown++;
                }else {
                    leftUPToDown=0;
                }
                if(leftUPToDown==5) return var;
            }
            //从左下到右上
            int leftDownToUP = 0;
            for(int i=x+4,j=y+4;i>x-5&&j>y-5;i--,j--) {
                if(i<0||i>=this.x||j<0||j>=this.y) continue;
                if(core[i][j]==var) {
                    leftDownToUP++;
                }else {
                    leftDownToUP=0;
                }
                if(leftDownToUP==5) return var;
            }
            return 0;
        }
        /**
         * 在该位置下棋  1:white 2:black
         * @param x 横坐标
         * @param y 纵坐标
         * @param var 棋子种类
         * @return 1:white 赢   2:black赢
         */
        public int ChessIt(int x,int y,int var) {
            if(__CanInput(x,y)) {
                core[x][y] =var;
                Chess chess = new Chess(x,y);
                stack.push(chess);
                return checkVictory(x, y, var);
            }
            else return -1;
        }

        //悔棋
        public boolean RetChess() {
            if(stack.isEmpty()) return false;
            Chess chess = stack.pop();
            core[chess.x][chess.y]= 0;
            return true;
        }
        //获得棋盘状态
        public int[][] getCore(){
            return this.core;
        }
        //重新开始
        public void Restart() {
            for(int i=0;i<this.x;i++) {
                for(int j=0;j<this.y;j++) {
                    this.core[i][j]=0;
                }
            }
            this.stack.clear();
        }
    /*
创建评分表
 */
    static final int[][] score = {
            { 0, 0,  0,  0,   0,10000 },//防守2子
            { 0, 0, 20,100, 500,10000 },//防守1子
            { 0,20,100,500,2500,10000 } //防守0子
    };
    public int AI(int[][] board){
        int max =  0;
        ArrayList<Integer> X = new ArrayList<>();
        ArrayList<Integer> Y = new ArrayList<>();
        //遍历棋盘
        for (int i = 0; i < board.length; ++i) {
            for (int j = 0; j < board.length; ++j) {
                //判断是否为空位
                if (__CanInput(i,j)) {
                    //进攻还是防守，寻找利益最大值
                    int score = max(getScore(board, i, j,2),getScore(board,i,j,1));
                    //以防有多个相同的最大值
                    if (score >= max) {
                        if (score > max) {
                            X.clear();
                            Y.clear();
                            max = score;
                        }
                        X.add(i);
                        Y.add(j);
                    }
                }
            }
        }
        //在最大值中任取一个返回,大部分情况只有一个
        Random r = new Random(X.size());
        int rr = r.nextInt(X.size());
        int x = X.get(rr);
        int y = Y.get(rr);
        if (__CanInput(x,y)){
            board[x][y] = 2; //将黑子落在这个位置
        }
        return checkVictory(x,y,2);

    }
    /*
       评分估测
        */
    //米字型搜索
    //[—, | , / , \]四个移动方向
    static int inX[] = { 1,0,1,1 };
    static int inY[] = { 0,1,1,-1 };
    public int getScore(int[][] board,int x,int y,int color){
        //返回评分值
        int re = 0;

        //向 [—,|, /, \]四个方向搜索，对应inX，inY
        for (int i = 0; i < 4; ++i) {
            //k记录连子两侧空位的数目（非墙，非敌方落子）
            int k = 0;
            //记录连子的数目，初始值为1因为假设在当前位置落子
            int count = 1;

            //[—,|, /, \]四个方向的正负方向
            for (int j = -1; j < 2; j += 2) {
                int dx = x + j * inX[i];
                int dy = y + j * inY[i];

                //判断是否超出棋盘边界
                while (dx >= 0 && dx < board.length &&
                        dy >= 0 && dy < board.length) {
                    //假如遇到颜色相同的子，count+1，反之则退出循环，并判断此时有无空位
                    if (board[dx][dy]==color) {
                        ++count;
                    }
                    else {
                        if (__CanInput(dx,dy)) ++k;
                        break;
                    }

                    dx += j * inX[i];
                    dy += j * inY[i];
                }
            }

            //假如连子大于5，使之等于5
            if (count > 5) count = 5;

            //加上该方向所得评分
            re += score[k][count];
        }

        return re;
    }
}
